package user

import (
    "crypto/md5"
    "errors"
    "fmt"
    "go-iot/app/models"
    "go-iot/app/common/mysql"
    "gorm.io/gorm"
    "time"
    "go-iot/app/common/logger"
)


type UserDTO struct {
    models.User
    RoleId int64 `json:"roleId"`
}

func PageUser(page *models.PageQuery, createId int64) (*models.PageResult[models.User], error) {
    var user []models.User
    var total int64

    query := mysql.DB.Model(&models.User{}).Where("create_id = ?", createId)
    
    // 添加条件过滤
    for _, condition := range page.Condition {
        query = query.Where(condition)
    }

    // 获取总数
    if err := query.Count(&total).Error; err != nil {
        return nil, fmt.Errorf("查询总数失败: %v", err)
    }

    // 执行分页查询
    if err := query.Order("create_time desc, id desc").
        Offset(page.PageOffset()).
        Limit(page.PageSize).
        Find(&user).Error; err != nil {
        return nil, fmt.Errorf("分页查询失败: %v", err)
    }

    // 清除密码
    for i := range user {
        user[i].Password = ""
    }

    result := models.PageUtil(total, page.PageNum, page.PageSize, user)
    return &result, nil
}

func AddUser(ob *UserDTO) error {
    if len(ob.Password) == 0 {
        return errors.New("password must be present")
    }

    var existUser models.User
    result := mysql.DB.Where("username = ?", ob.Username).First(&existUser)
    if result.Error != nil && result.Error != gorm.ErrRecordNotFound {
        return result.Error
    }
    if result.Error == nil {
        return errors.New("user exist")
    }

    u := &ob.User
    Md5Pwd(u)
    u.CreateTime = time.Now()

    if err := mysql.DB.Create(u).Error; err != nil {
        return err
    }

    if ob.RoleId > 0 {
        if err := AddUserRelRole(u.Id, ob.RoleId); err != nil {
            mysql.DB.Delete(u)
            return err
        }
    }
    return nil
}

func UpdateUser(ob *UserDTO) error {
    if len(ob.Nickname) == 0 {
        return fmt.Errorf("nickname must be present")
    }

    updates := map[string]interface{}{
        "nickname": ob.Nickname,
    }

    if err := mysql.DB.Model(&ob.User).Updates(updates).Error; err != nil {
        return err
    }

    if err := DeleteUserRelRoleByUserId(ob.Id); err != nil {
        return err
    }

    return AddUserRelRole(ob.Id, ob.RoleId)
}

func UpdateUserBaseInfo(ob *UserDTO) error {
    if len(ob.Nickname) == 0 {
        return fmt.Errorf("nickname must be present")
    }

    updates := map[string]interface{}{
        "nickname": ob.Nickname,
    }

    return mysql.DB.Model(&ob.User).Updates(updates).Error
}

func UpdateUserPwd(ob *models.User) error {
    if ob.Id == 0 {
        return errors.New("id must be present")
    }
    if len(ob.Username) == 0 {
        return errors.New("username must be present")
    }

    Md5Pwd(ob)
    return mysql.DB.Model(ob).Update("password", ob.Password).Error
}

func Md5Pwd(ob *models.User) {
    data := []byte(ob.Username + ob.Password)
    has := md5.Sum(data)
    ob.Password = fmt.Sprintf("%x", has)
}

func UpdateUserEnable(ob *models.User) error {
    if ob.Id == 0 {
        return errors.New("id must be present")
    }
    return mysql.DB.Model(ob).Update("enable_flag", ob.EnableFlag).Error
}

func DeleteUser(ob *models.User) error {
    if err := mysql.DB.Delete(ob).Error; err != nil {
        logger.Errorf("delete fail %v", err)
        return err
    }
    return DeleteUserRelRoleByUserId(ob.Id)
}

func GetUser(id int64) (*UserDTO, error) {
    var user models.User
    if err := mysql.DB.First(&user, id).Error; err != nil {
        if err == gorm.ErrRecordNotFound {
            return nil, nil
        }
        return nil, err
    }

    dto := &UserDTO{User: user}
    list, err := GetUserRelRoleByUserId(id)
    if err != nil {
        logger.Errorf("GetUserRelRoleByUserId error: %v", err)
    }
    if len(list) > 0 {
        dto.RoleId = list[0].RoleId
    }
    return dto, nil
}

func GetUserByEntity(p models.User) (*models.User, error) {
    var user models.User
    query := mysql.DB.Model(&models.User{})

    if p.Id != 0 {
        query = query.Where("id = ?", p.Id)
    }
    if len(p.Username) > 0 {
        query = query.Where("username = ?", p.Username)
    }

    result := query.First(&user)
    if result.Error != nil {
        if result.Error == gorm.ErrRecordNotFound {
            return nil, nil
        }
        return nil, result.Error
    }
    return &user, nil
}
